import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class DraggableAutoMovingBallsGame extends JFrame {
    private final int WIDTH = 600;
    private final int HEIGHT = 400;
    private final int BALL_SIZE = 30;
    private final int MAX_BALLS = 10; // 最大小球数量

    private List<Ball> balls = new ArrayList<>();
    private List<Thread> ballThreads = new ArrayList<>(); // 存储所有小球线程
    private boolean gameOver = false;
    private boolean running = true;

    private JLabel statusLabel;
    private JLabel scoreLabel;
    private JButton addBallButton;
    private JButton resetButton;
    private int ballCount = 1; // 初始小球数量

    private long startTime; // 游戏开始时间
    private Timer timer;    // 计时器
    private int score = 0;  // 分数（秒数）

    public DraggableAutoMovingBallsGame() {
        // 初始化小球
        addNewBall();
        startTime = System.currentTimeMillis(); // 记录游戏开始时间

        // 设置计时器，每秒更新一次分数
        timer = new Timer(1000, e -> {
            if (!gameOver && running) {
                score = (int)((System.currentTimeMillis() - startTime) / 1000);
                scoreLabel.setText("分数: " + score + " 秒");
            }
        });
        timer.start();

        // 创建GUI
        JPanel gamePanel = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                if (!gameOver) {
                    // 绘制所有小球
                    for (Ball ball : balls) {
                        g.setColor(ball.color);
                        g.fillOval(ball.x, ball.y, BALL_SIZE, BALL_SIZE);
                    }
                } else {
                    g.setColor(Color.RED);
                    g.setFont(new Font("Arial", Font.BOLD, 24));
                    g.drawString("游戏结束！小球碰撞！", WIDTH / 2 - 100, HEIGHT / 2);
                    g.drawString("最终分数: " + score + " 秒", WIDTH / 2 - 60, HEIGHT / 2 + 30);
                }
            }
        };

        statusLabel = new JLabel("游戏进行中... 小球数量: " + ballCount, SwingConstants.CENTER);
        scoreLabel = new JLabel("分数: 0 秒", SwingConstants.CENTER);

        addBallButton = new JButton("增加小球");
        resetButton = new JButton("重置游戏");

        // 控制面板
        JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 10));
        controlPanel.add(addBallButton);
        controlPanel.add(resetButton);

        // 分数面板
        JPanel scorePanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 10));
        scorePanel.add(statusLabel);
        scorePanel.add(scoreLabel);

        // 设置布局
        this.setLayout(new BorderLayout());
        this.add(gamePanel, BorderLayout.CENTER);
        this.add(controlPanel, BorderLayout.NORTH);
        this.add(scorePanel, BorderLayout.SOUTH);

        // 设置窗口属性
        this.setTitle("小球碰撞游戏");
        this.setSize(WIDTH, HEIGHT + 100);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);
        this.setResizable(false);

        // 添加鼠标监听器
        gamePanel.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                if (!gameOver) {
                    // 找到被点击的小球
                    for (Ball ball : balls) {
                        if (e.getX() >= ball.x && e.getX() <= ball.x + BALL_SIZE &&
                                e.getY() >= ball.y && e.getY() <= ball.y + BALL_SIZE) {
                            ball.isDragged = true;
                            ball.dragOffsetX = e.getX() - ball.x;
                            ball.dragOffsetY = e.getY() - ball.y;
                            ball.dx = 0; // 拖动时暂停自动移动
                            ball.dy = 0;
                            break;
                        }
                    }
                }
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                if (!gameOver) {
                    for (Ball ball : balls) {
                        if (ball.isDragged) {
                            ball.isDragged = false;
                            // 放开后重新随机分配速度
                            resetBallSpeed(ball);
                        }
                    }
                }
            }
        });

        gamePanel.addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                if (!gameOver) {
                    for (Ball ball : balls) {
                        if (ball.isDragged) {
                            ball.x = e.getX() - ball.dragOffsetX;
                            ball.y = e.getY() - ball.dragOffsetY;

                            // 限制小球在窗口内
                            ball.x = Math.max(0, Math.min(WIDTH - BALL_SIZE, ball.x));
                            ball.y = Math.max(0, Math.min(HEIGHT - BALL_SIZE, ball.y));
                        }
                    }
                    repaint();
                }
            }
        });

        // 按钮事件监听
        addBallButton.addActionListener(e -> {
            if (ballCount < MAX_BALLS) {
                ballCount++;
                addNewBall();
                statusLabel.setText("游戏进行中... 小球数量: " + ballCount);
            } else {
                JOptionPane.showMessageDialog(this, "最多只能有" + MAX_BALLS + "个小球！", "提示", JOptionPane.INFORMATION_MESSAGE);
            }
        });

        resetButton.addActionListener(e -> resetGame());
    }

    private void addNewBall() {
        Random random = new Random();
        Color color = new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256));
        Ball newBall = new Ball(
                random.nextInt(WIDTH - BALL_SIZE),
                random.nextInt(HEIGHT - BALL_SIZE),
                random.nextInt(5) + 1, // 初始速度
                random.nextInt(5) + 1,
                color
        );
        balls.add(newBall);

        // 为新小球创建并启动新线程
        Thread ballThread = new Thread(new BallMover(newBall));
        ballThread.start();
        ballThreads.add(ballThread);
    }

    private void resetBallSpeed(Ball ball) {
        Random random = new Random();
        ball.dx = random.nextInt(5) + 1; // 重新分配随机速度
        ball.dy = random.nextInt(5) + 1;
    }

    private void resetGame() {
        // 停止所有小球线程
        running = false;
        for (Thread thread : ballThreads) {
            try {
                thread.join(); // 等待所有线程结束
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }

        // 重置游戏状态
        gameOver = false;
        running = true;
        balls.clear();
        ballThreads.clear();
        ballCount = 1;
        score = 0;
        startTime = System.currentTimeMillis(); // 重置开始时间

        // 重启计时器
        timer.stop();
        timer = new Timer(1000, e -> {
            if (!gameOver && running) {
                score = (int)((System.currentTimeMillis() - startTime) / 1000);
                scoreLabel.setText("分数: " + score + " 秒");
            }
        });
        timer.start();

        addNewBall();
        statusLabel.setText("游戏进行中... 小球数量: " + ballCount);
        scoreLabel.setText("分数: 0 秒");
        repaint();
    }

    private class BallMover implements Runnable {
        private final Ball ball;

        public BallMover(Ball ball) {
            this.ball = ball;
        }

        @Override
        public void run() {
            while (running && !gameOver) {
                // 只有未被拖动时才移动小球
                if (!ball.isDragged) {
                    ball.x += ball.dx;
                    ball.y += ball.dy;

                    // 检测边界碰撞
                    if (ball.x <= 0 || ball.x >= WIDTH - BALL_SIZE) {
                        ball.dx = -ball.dx; // 反弹
                    }
                    if (ball.y <= 0 || ball.y >= HEIGHT - BALL_SIZE) {
                        ball.dy = -ball.dy; // 反弹
                    }
                }

                // 检测小球间碰撞
                if (checkCollisions()) {
                    gameOver = true;
                    timer.stop(); // 停止计时器
                    statusLabel.setText("游戏结束！小球碰撞！");
                    JOptionPane.showMessageDialog(DraggableAutoMovingBallsGame.this,
                            "游戏结束！小球碰撞！\n最终分数: " + score + " 秒",
                            "游戏结束",
                            JOptionPane.INFORMATION_MESSAGE);
                }

                // 更新界面
                SwingUtilities.invokeLater(() -> repaint());

                try {
                    Thread.sleep(16); // 约60FPS
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }
    }

    private boolean checkCollisions() {
        for (int i = 0; i < balls.size(); i++) {
            for (int j = i + 1; j < balls.size(); j++) {
                Ball ball1 = balls.get(i);
                Ball ball2 = balls.get(j);

                // 计算两个球体中心之间的距离
                int dx = ball1.x + BALL_SIZE / 2 - (ball2.x + BALL_SIZE / 2);
                int dy = ball1.y + BALL_SIZE / 2 - (ball2.y + BALL_SIZE / 2);
                double distance = Math.sqrt(dx * dx + dy * dy);

                if (distance < BALL_SIZE) {
                    return true;
                }
            }
        }
        return false;
    }

    private class Ball {
        int x, y;
        int dx, dy; // 速度
        Color color;
        boolean isDragged = false;
        int dragOffsetX, dragOffsetY;

        public Ball(int x, int y, int dx, int dy, Color color) {
            this.x = x;
            this.y = y;
            this.dx = dx;
            this.dy = dy;
            this.color = color;
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new DraggableAutoMovingBallsGame().setVisible(true));
    }
}